﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharpTest.Net.Collections;

namespace TEAA
{
    public class BPlusTreeIndex<Type> : Index<Type>
    {

        private BPlusTree<Type, List<RecordID>> index;

        public BPlusTreeIndex(string indexPath)
        {
            BPlusTree<Type, List<RecordID>>.Options o = new BPlusTree<Type, List<RecordID>>.Options(new GenericPrimitiveSerializer<Type>(), new RecordIDListSerializer())
            {
                BTreeOrder = 100,
                FileName = indexPath,
                CreateFile = CreatePolicy.IfNeeded,
                StorageType = StorageType.Disk,

            };
            index = new BPlusTree<Type, List<RecordID>>(o);
            index.EnableCount();
        }

        public void InitializeIndex(IDictionary<Type, List<RecordID>> indexData) 
        {
            index.Clear();
            foreach (KeyValuePair<Type, List<RecordID>> data in indexData)
                AddIndexedRow(data.Key, data.Value);
        }

        public void AddIndexedRow(Type key, List<RecordID> rid)
        {
            KeyValuePair<Type, List<RecordID>> data = new KeyValuePair<Type, List<RecordID>>(key, rid);
            data.Value.AddRange(GetIndexedRowValue(data.Key));
            data.Value.Sort(new RecordIDComparator());
            RemoveIndexedRow(data.Key);
            index.Add(data.Key, data.Value.Distinct().ToList());
        }

        public void RemoveIndexedRow(Type key)
        {
            index.Remove(key);
        }

        public List<RecordID> GetIndexedRowValue(Type key)
        {
            try
            {
                return index[key];
            }
            catch (Exception)
            {
                return new List<RecordID>();
            }
        }

        public List<RecordID> GetIndexedRowsValueFromRange(Type startKey, Type endKey)
        {
            List<RecordID> values = new List<RecordID>();
            IEnumerator<KeyValuePair<Type, List<RecordID>>> enumerator = index.GetEnumerator();
            
            bool hasData = enumerator.MoveNext();
            while(hasData && !enumerator.Current.Key.Equals(startKey))
                hasData = enumerator.MoveNext();

            while(hasData && !enumerator.Current.Key.Equals(endKey))
            {
                values.AddRange(enumerator.Current.Value);
                hasData = enumerator.MoveNext();
            }

            if (hasData.Equals(true))
            {
                values.AddRange(enumerator.Current.Value);
                hasData = enumerator.MoveNext();
            }
            else
                values.Clear();

            return values;
        }

    }
}
